package com.yingside.thread.consume;

public class ProduceConsume {
    public static void main(String[] args) {
        SynStack ss = new SynStack();
        //生产者与消费者的线程
        Producer producer = new Producer(ss);
        Consume consume = new Consume(ss);

        Thread tp = new Thread(producer);
        tp.start();

        Thread tc = new Thread(consume);
        tc.start();
    }


}

//馒头
class SteamBread{
    int id;
    public SteamBread(int id){
        this.id = id;
    }

    @Override
    public String toString() {
        return "SteamBread:" + id;
    }
}

//馒头筐
//生产者线程和消费者现在都需要去抢夺的资源
class SynStack{
    int index = 0;
    SteamBread [] bs = new SteamBread[6];

    public synchronized void push(SteamBread bread){
        try {
            //如果发现当前的馒头筐满了，进行等待
            while(index == bs.length){
                this.wait();
                System.out.println("--->馒头筐已经满了,请稍后再进行生产");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //如果没有满，唤醒线程
        this.notifyAll();
        //往数组中填入数据
        bs[index] = bread;
        this.index ++;
    }

    public synchronized SteamBread pop(){
        //如果馒头筐空了，消费者需要等待
        while(index == 0){
            try {
                this.wait();
                System.out.println("--->馒头筐已经空了,请稍后再消费");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //如果没有满，直接唤醒
        this.notifyAll();
        this.index--;
        return bs[index];
    }
}

class Producer implements Runnable {

    SynStack ss = null;

    public Producer(SynStack ss){
        this.ss = ss;
    }

    public void run() {
        //模拟数据，一直往馒头筐中加入馒头
        for (int i = 0; i < 20; i++) {
            SteamBread sb = new SteamBread(i);
            ss.push(sb);
            System.out.println("生产了：" + sb);

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consume implements Runnable {

    SynStack ss = null;

    public Consume(SynStack ss){
        this.ss = ss;
    }

    public void run() {
        //模拟数据，一直从馒头筐中消费馒头
        for (int i = 0; i < 20; i++) {
            SteamBread sb = ss.pop();
            System.out.println("消费了:" + sb);

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
